/*
 * Copyright (C) 2015 yixun All Rights Reserved.
 *
 * AreaServiceImpl.java
 */
package com.yixun.qfbao.api.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.yixun.qfbao.api.service.*;
import com.yixun.qfbao.apidto.*;
import com.yixun.qfbao.apidto.base.CommonResDTO;
import com.yixun.qfbao.apidto.v10dto.BaseResponseDto;
import com.yixun.qfbao.apidto.v10dto.DeptV10;
import com.yixun.qfbao.config.M2ApiConfig;
import com.yixun.qfbao.config.V10ApiConfig;
import com.yixun.qfbao.constant.StringConstant;
import com.yixun.qfbao.dao.ApiLogDao;
import com.yixun.qfbao.dao.DepartmentDao;
import com.yixun.qfbao.dao.OtherCompanyDao;
import com.yixun.qfbao.model.PasswordUtil;
import com.yixun.qfbao.model.*;
import com.yixun.qfbao.model.dto.*;
import com.yixun.qfbao.model.enums.*;
import com.yixun.qfbao.service.CompanyService;
import com.yixun.qfbao.service.*;
import com.yixun.qfbao.util.*;
import com.yixun.qfbao.xf.model.Premises;
import com.yixun.qfbao.xf.model.dto.CustomerPremisesDto;
import com.yixun.qfbao.xf.model.enums.*;
import com.yixun.qfbao.xf.service.CustomerPremisesService;
import com.yixun.qfbao.xf.service.PremisesService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ReceiveIntentionServiceImpl implements ReceiveIntentionService {

    @Autowired
    M2ApiConfig m2ApiConfig;
    @Autowired
    V10ApiConfig v10ApiConfig;
    @Autowired
    private ApiLogDao apiLogDao;
    @Autowired
    private ReportCommonService reportCommonService;
    @Autowired
    private PartnerInfoService partnerInfoService;
    @Autowired
    private CompanyService companyService;
    @Autowired
    private DepartmentDao departmentDao;
    @Autowired
    private PremisesService premisesService;
    @Autowired
    private CustomerPremisesService customerPremisesService;
    @Autowired
    private OtherSysUserService otherSysUserService;
    @Autowired
    private OtherCompanyDao otherCompanyDao;
    @Autowired
    private ReportVisitService reportVisitService;
    @Autowired
    private V10BindService v10BindService;
    @Autowired
    private PremisesRelationExternalService premisesRelationExternalService;
    @Autowired
    private ReportExternalService reportExternalService;
    @Autowired
    private OtherSysDeptService otherSysDeptService;
    @Autowired
    private ReportModelApiService reportModelApiService;
    @Autowired
    private WxTemplateMsgService wxTemplateMsgService;
    @Autowired
    private PremisesOverdueService premisesOverdueService;
    @Autowired
    DeptPermissionService deptPermissionService;
    @Autowired
    private AuditReportService auditReportService;

    public static ConcurrentHashMap<String, ReceiveIntentionReqDto> concurrentHashMap = new ConcurrentHashMap<>();

    @Override
    public ReceiveIntentionResDto receiveIntentionCheck(ReceiveIntentionReqDto reqDto, String devCompanyUuid) {
        ReceiveIntentionResDto resDto = new ReceiveIntentionResDto();
        resDto.setResult(ResultEnum.SUCCESS.getNo());
        resDto.setResultMsg(ResultEnum.SUCCESS.getDes());

        //.检查楼盘
        Premises premises = premisesService.selectSimpleById(Long.parseLong(reqDto.getPremisesId()));
        try {
            //获取公司信息
            OtherCompanyDto otherCompanyDto = new OtherCompanyDto();
            otherCompanyDto.setCompanyUuid(reqDto.getCompanyUuid());
            otherCompanyDto.setIsDeleted(DelFlagEnum.UNDEL.getNo());
            List<OtherCompany> otherCompanyList = otherCompanyDao.selectListByDto(otherCompanyDto);
            if (CollectionUtils.isEmpty(otherCompanyList)) {
                resDto.setResult(ResultEnum.FAIL.getNo());
                resDto.setResultMsg("公司信息不存在");
                return resDto;
            }

            if (Objects.isNull(premises) ||
                    DelFlagEnum.DEL.getNo().equals(premises.getDelFlag()) ||
                    PremisesStatusEnum.type0.getNo().equals(premises.getPremisesStatus()) ||
                    SaleStatusEnum.type_3.getNo().equals(premises.getSaleStatus())) {
                resDto.setResult(ResultEnum.FAIL.getNo());
                resDto.setResultMsg("楼盘已无效或未上架，无法报备！");
                return resDto;
            }

            if (reqDto.getReportVisit().getVisitTime() != null) {
                // 最短报备保护时间
                boolean checkSepcilTimeFlag = customerPremisesService.checkSpecialTime(reqDto.getReportVisit().getVisitTime().getTime(), premises);
                if (!checkSepcilTimeFlag) {
                    resDto.setResultMsg("小于最短报备时间,报备无效");
                    resDto.setResult(ResultEnum.FAIL.getNo());
                    return resDto;
                }
            }

            boolean visitFlag = customerPremisesService.checkVisitRepeat(0L, premises, reqDto.getMobile());
            if (visitFlag) {
                //002 客户已到访
                String errorMsg = "该客户: " + reqDto.getMobile() + "已到访该楼盘【" + premises.getName() + "】无法再次报备!";
                resDto.setResultMsg(errorMsg);
                resDto.setResult(ResultEnum.FAIL.getNo());
                return resDto;
            }
            resDto.setResult(ResultEnum.SUCCESS.getNo());
            resDto.setResultMsg(ResultEnum.SUCCESS.getDes());

        } catch (Exception e) {
            log.error("报备信息验证失败: {}", e);
            resDto.setResultMsg("报备信息验证失败" + e.getMessage());
            concurrentHashMap.remove(reqDto.getEmployeeUuid());
            String errorMsg = "报备信息验证失败 ";
            if (e instanceof RuntimeException) {
                errorMsg += e.getMessage();
            } else {
                errorMsg += "请联系客服人员";
            }
            resDto.setResult("4");
            resDto.setResultMsg(errorMsg);
        }finally {
            ApiLogDto apiLogDto = new ApiLogDto();
            apiLogDto.setUrl("/channel-openapi/v10/premises/receiveIntentionCheck");
            apiLogDto.setBusinessType(ApiActionEnum.REPORT_ADD.getNo());
            apiLogDto.setRequestType(1);
            apiLogDto.setRequestContent(JSONObject.toJSONString(reqDto));
            apiLogDto.setPremisesId(premises.getId());
            apiLogDto.setPremisesName(premises.getName());
            apiLogDto.setCompanyId(premises.getCompanyId());
            apiLogDto.setOtherCompanyId(reqDto.getCompanyUuid());
            apiLogDto.setResponseContent(JSONObject.toJSONString(resDto));
            apiLogDao.create(apiLogDto);
        }

        return resDto;
    }

    @Override
    @Async
    public ReceiveIntentionResDto receiveIntention(ReceiveIntentionReqDto reqDto, String agencyAccessToken, String assistantAccessToken, String devCompanyUuid) {
        ReceiveIntentionResDto resDto = new ReceiveIntentionResDto();
        resDto.setResult(ResultEnum.FAIL.getNo());
        String remark = "";

        OtherCompany otherCompany = new OtherCompany();
        Premises premises = premisesService.selectSimpleById(Long.parseLong(reqDto.getPremisesId()));
        OtherSysUser otherSysUser = new OtherSysUser();
        Map<String, String> resultMap = new HashMap<>();
        try {
            // 1、公司绑定关系检查
            OtherCompanyDto otherCompanyDto = new OtherCompanyDto();
            otherCompanyDto.setCompanyUuid(reqDto.getCompanyUuid());
            otherCompanyDto.setIsDeleted(DelFlagEnum.UNDEL.getNo());
            List<OtherCompany> otherCompanyList = otherCompanyDao.selectListByDto(otherCompanyDto);
            if (CollectionUtils.isEmpty(otherCompanyList)) {
                resDto.setResultMsg("公司信息不存在");
                return resDto;
            }
            otherCompany = otherCompanyList.get(0);
            // 2、楼盘是否有效检查
            if (Objects.isNull(premises) ||
                    DelFlagEnum.DEL.getNo().equals(premises.getDelFlag()) ||
                    PremisesStatusEnum.type0.getNo().equals(premises.getPremisesStatus()) ||
                    SaleStatusEnum.type_3.getNo().equals(premises.getSaleStatus())) {
                resDto.setResult("4");
                resDto.setResultMsg("楼盘已无效或未上架，无法报备！");
                return resDto;
            }
            // 3.更新人员
            synchronized (concurrentHashMap) {
                if (!isInUserMap(reqDto)) {
                    otherSysUser = syncSaasUser(reqDto, otherCompany, premises.getCompanyId());
                    log.info("receiveIntentionService --> receiveIntention --> companyUuid-employeeUuid-employeePhone: {}, premisesId: {}, mobile: {}, otherSysUser: {}",
                            reqDto.getCompanyUuid() + "-" + reqDto.getEmployeeUuid() + "-" + reqDto.getEmployeePhone(),
                            reqDto.getPremisesId(),
                            reqDto.getMobile(),
                            JSONObject.toJSONString(otherSysUser));
                    concurrentHashMap.remove(reqDto.getEmployeeUuid());
                }
            }
            // 4.添加报备信息,写跟进
            log.info("V10报备,获取消息推送信息: companyUuid = " + devCompanyUuid + ", agencyToken = " + agencyAccessToken + ", assistantToken = " + assistantAccessToken);
            resultMap = addReportInfoFromV10(reqDto, premises, otherSysUser, agencyAccessToken, assistantAccessToken, devCompanyUuid);
            log.info("receiveIntention resultMap: {}", JSONObject.toJSONString(resultMap));
            // Saas1.0-->通用版的商户-->不推送消息
            if (!"weihaianbangruidedic_company1413027af".equals(reqDto.getCompanyUuid()) && !"chengdouqiaofangxinx_companyf9413b81c".equals(reqDto.getCompanyUuid())) {
                if( FreeAuditEnum.FREE_REPORT_AUDIT.getNo().equals(premises.getFreeAudit()) && (ReceiveIntentionErrorCodeEnum.CODE_000.getNo()).equals(resultMap.get("errorCode"))){
                    resultMap.put("errorCode", ReceiveIntentionErrorCodeEnum.CODE_009.getNo());
                }
                noticeV10ForReport(resultMap, reqDto, otherCompany.getChannelCompanyId(), premises);
            }
            // 4.添加更新信息
            if (resultMap.containsKey("reportId")) {
                resDto.setIntentionId(resultMap.get("reportId"));
            }
            if (resultMap.containsKey("remark")) {
                remark = resultMap.get("remark");
                log.info("remark=============>" + resultMap.get("remark"));
            }
            resDto.setResult(resultMap.get("success"));
            resDto.setResultMsg(resultMap.get("msg"));

            /**
             * 报备免审
             */
            if (FreeAuditEnum.FREE_REPORT_AUDIT.getNo().equals(premises.getFreeAudit())) {
                // 判断是否需要自动审核通过
                AuditCPReqDto auditCPReqDto = new AuditCPReqDto();
                auditCPReqDto.setId(String.valueOf(resDto.getIntentionId()));
                auditCPReqDto.setCustomerStatus(CustomerStatusEnum.not_visited.getNo());
                auditCPReqDto.setRemark("报备免审");
                auditCPReqDto.setUserId(String.valueOf(otherSysUser.getChannelPartnerId()));
                auditCPReqDto.setLoginType(SystemIdEnum.DEVELOPERS.getCode());
                auditCPReqDto.setCreateTime(null);
                auditCPReqDto.setAffixList(null);
                auditReportService.auditCP(auditCPReqDto, null, assistantAccessToken);
            }

        } catch (Exception e) {
            log.error("同步报备信息失败: {}", e);
            resDto.setResultMsg("同步报备信息失败" + e.getMessage());
            concurrentHashMap.remove(reqDto.getEmployeeUuid());
            String errorMsg = "同步报备信息失败 ";
            if (e instanceof RuntimeException) {
                errorMsg += e.getMessage();
            } else {
                errorMsg += "请联系客服人员";
            }
            v10BindService.synsNoticeForReport(reqDto.getReportVisit().getIntentionUuid(), ReceiveIntentionErrorCodeEnum.CODE_FILE.getNo(), otherCompany.getChannelCompanyId(), errorMsg);
        }
        log.info("remark=============>" + remark);
        ApiLogDto apiLogDto = new ApiLogDto();
        apiLogDto.setUrl("/channel-openapi/v10/premises/receiveIntention");
        apiLogDto.setBusinessType(ApiActionEnum.REPORT_ADD.getNo());
        apiLogDto.setRequestType(1);
        apiLogDto.setRequestContent(JSONObject.toJSONString(reqDto));
        apiLogDto.setPremisesId(premises.getId());
        apiLogDto.setPremisesName(premises.getName());
        apiLogDto.setCompanyId(premises.getCompanyId());
        apiLogDto.setPartnerId(otherSysUser.getChannelPartnerId());
        apiLogDto.setPartnerName(otherSysUser.getUserName());
        apiLogDto.setAgentCompanyId(otherSysUser.getCompanyId());
        apiLogDto.setOtherCompanyId(reqDto.getCompanyUuid());
        if (resultMap.containsKey("reportId")) {
            apiLogDto.setOtherRelationId(resultMap.get("reportId"));
            apiLogDto.setBusinessTime(DateUtils.StringToDate(resultMap.get("reportDate"), DateStyle.YYYY_MM_DD_HH_MM_SS));
        }
        apiLogDto.setResponseContent(JSONObject.toJSONString(resDto));
        apiLogDao.create(apiLogDto);

        return resDto;
    }

    /**
     * 报备再次约看信息
     *
     * @param reqDto
     * @return
     */
    @Override
    @Transactional
    public ReceiveVisitResDto receiveVisit(ReceiveVisitReqDto reqDto) {
        ReceiveVisitResDto resDto = new ReceiveVisitResDto();
        resDto.setResult(ResultEnum.FAIL.getNo());
        //0.验证参数
        if (reqDto.getIntentionUuid() == null) {
            resDto.setResultMsg("报备uuid不能为空");
            return resDto;
        }
        if (reqDto.getVisitTime() != null) {
            if (reqDto.getVisitTime().before(new Date())) {
                resDto.setResultMsg("到访时间不能小于当前时间");
            }
        } else {
            resDto.setResultMsg("到访时间不能为空");
        }

        try {
            //1.添加约看信息
            ReportVisitDto reportVisit = new ReportVisitDto();
            BeanUtils.copyProperties(reqDto, reportVisit);
            //1.1 查询报备信息 从约看信息中找出v10 channel 报备对应关系
            ReportExternalDto reportExternal = new ReportExternalDto();
            reportExternal.setIsDeleted(DelFlagEnum.UNDEL.getNo());
            reportExternal.setSysId(ExternalSysEnum.V10.getCode());
            reportExternal.setReportUuid(reqDto.getIntentionUuid());
            List<ReportExternal> reportExternalList = reportExternalService.selectListByDto(reportExternal);
            if (reportExternalList == null || reportExternalList.size() == 0) {
                resDto.setResultMsg("报备不存在");
                return resDto;
            }

            reportVisit.setIntentionUuid(reqDto.getIntentionUuid());
            reportVisit.setReportId(reportExternalList.get(0).getReportId());
            reportVisit.setCreateTime(new Date());
            reportVisit.setIsDeleted(DelFlagEnum.UNDEL.getNo());
            reportVisit.setPremisesId(ParseUtils.toLong(reqDto.getPremisesId()));

            reportVisitService.create(reportVisit);
            //2.更新报备的带看时间
            CustomerPremisesDto cpDto = new CustomerPremisesDto();
            cpDto.setId(reportExternalList.get(0).getReportId());
            cpDto.setHopeVisitTime(reportVisit.getVisitTime());
            customerPremisesService.update(cpDto);

            resDto.setResult(ResultEnum.SUCCESS.getNo());
            return resDto;
        } catch (Exception e) {
            log.error("添加约看信息失败: {}", e);
            resDto.setResultMsg("添加约看信息失败: " + e.getMessage());
            return resDto;
        }
    }


    @Transactional
    public OtherSysUser syncSaasUser(ReceiveIntentionReqDto reqDto, OtherCompany otherCompany, Long devCompany) {
        // 绑定的分销公司
        Long agentCompany = otherCompany.getChannelCompanyId();
        // 分销公司顶级部门
        DepartmentDto department = new DepartmentDto();
        department.setMerchantId(agentCompany);
        department.setParentId(0L);
        department.setDelFlag(DelFlagEnum.UNDEL.getNo());
        Department topDept = departmentDao.selectByDto(department);

        Department saasUserDept = syncSaasUserDept(reqDto, otherCompany, topDept);
        log.info("receiveIntentionService --> receiveIntention --> companyUuid-employeeUuid-employeePhone: {}, premisesId: {}, mobile: {}, saasUserDept: {}",
                reqDto.getCompanyUuid() + "-" + reqDto.getEmployeeUuid() + "-" + reqDto.getEmployeePhone(),
                reqDto.getPremisesId(),
                reqDto.getMobile(),
                JSONObject.toJSONString(saasUserDept));
        return bindSaasUser(reqDto, otherCompany, saasUserDept, devCompany);
    }

    public Department syncSaasUserDept(ReceiveIntentionReqDto reqDto, OtherCompany otherCompany, Department topDept) {
        Department department = analysisDept(reqDto, topDept, otherCompany.getSyncMode());
        //部门最后添加失败 则人员挂到该分销公司下
        if (Objects.isNull(department)) {
            department = topDept;
        }else {
            // 刷新公司部门权限
            deptPermissionService.initDeptPermissionCode(department.getMerchantId());
        }
        return department;
    }

    public Department analysisDept(ReceiveIntentionReqDto reqDto, Department topDept, String syncMode) {
        List<DeptV10> deptV10s = reqDto.getDepts();
        deptV10s.sort(Comparator.comparingInt(DeptV10::getLayer));
        Map<String, DeptV10> deptV10Map = deptV10s.stream().collect(Collectors.toMap(DeptV10::getDeptUuid, Function.identity()));
        // 用户当前所属部门
        DeptV10 userDeptV10 = deptV10Map.get(reqDto.getEmployeeDeptNo());
        // 需同步的Saas部门
        List<DeptV10> finalSyncDeptList = new ArrayList<>();
        if (SyncModeEnum.NORMAL.getCode().equals(syncMode)) {
            String employeeDeptNo = reqDto.getEmployeeDeptNo();
            for (DeptV10 deptV10 : deptV10s) {
                if((deptV10.getLayer() == 1 || deptV10.getLayer() == 2) && finalSyncDeptList.size() < 2){
                    finalSyncDeptList.add(deptV10);
                }
                // 获取到用户所在部门,直接添加用户这一层部门
                if(employeeDeptNo.equals(deptV10.getDeptNo())){
                    break;
                }
            }
        } else if (SyncModeEnum.WANHAO.getCode().equals(syncMode)) {
            DeptV10 selfDeptV10 = null;
            String parenetUuid = null;
            String employeeDeptNo = reqDto.getEmployeeDeptNo();
            for (DeptV10 deptV10 : deptV10s) {
                if (deptV10.getDeptNo().equals(employeeDeptNo)) {
                    selfDeptV10 = deptV10;
                    if (employeeDeptNo.equals(selfDeptV10.getDeptUuid8())) {
                        parenetUuid = selfDeptV10.getDeptUuid7();
                    } else if (employeeDeptNo.equals(selfDeptV10.getDeptUuid7())) {
                        parenetUuid = selfDeptV10.getDeptUuid6();
                    } else if (employeeDeptNo.equals(selfDeptV10.getDeptUuid6())) {
                        parenetUuid = selfDeptV10.getDeptUuid5();
                    } else if (employeeDeptNo.equals(selfDeptV10.getDeptUuid5())) {
                        parenetUuid = selfDeptV10.getDeptUuid4();
                    } else if (employeeDeptNo.equals(selfDeptV10.getDeptUuid4())) {
                        parenetUuid = selfDeptV10.getDeptUuid3();
                    } else if (employeeDeptNo.equals(selfDeptV10.getDeptUuid3())) {
                        parenetUuid = selfDeptV10.getDeptUuid2();
                    } else if (employeeDeptNo.equals(selfDeptV10.getDeptUuid2())) {
                        parenetUuid = selfDeptV10.getDeptUuid1();
                    }
                    break;
                }
            }
            if (StringUtils.isNotBlank(parenetUuid)) {
                DeptV10 parentDeptV10 = deptV10Map.get(parenetUuid);
                if(Objects.nonNull(parentDeptV10)){
                    finalSyncDeptList.add(parentDeptV10);
                }
            }
            finalSyncDeptList.add(selfDeptV10);
        } else if (SyncModeEnum.BANGFANG.getCode().equals(syncMode)) {
            DeptV10 selfDeptV10 = null;
            String parenetUuid = null;
            String employeeDeptNo = reqDto.getEmployeeDeptNo();
            for (DeptV10 deptV10: deptV10s) {
                if (deptV10.getDeptNo().equals(employeeDeptNo)) {
                    selfDeptV10 = deptV10;
                    if (employeeDeptNo.equals(selfDeptV10.getDeptUuid8())) {
                        parenetUuid = selfDeptV10.getDeptUuid6();
                    } else if (employeeDeptNo.equals(selfDeptV10.getDeptUuid7())) {
                        parenetUuid = selfDeptV10.getDeptUuid5();
                    } else if (employeeDeptNo.equals(selfDeptV10.getDeptUuid6())) {
                        parenetUuid = selfDeptV10.getDeptUuid4();
                    } else if (employeeDeptNo.equals(selfDeptV10.getDeptUuid5())) {
                        parenetUuid = selfDeptV10.getDeptUuid3();
                    } else if (employeeDeptNo.equals(selfDeptV10.getDeptUuid4())) {
                        parenetUuid = selfDeptV10.getDeptUuid2();
                    } else if (employeeDeptNo.equals(selfDeptV10.getDeptUuid3())) {
                        parenetUuid = selfDeptV10.getDeptUuid1();
                    } else if (employeeDeptNo.equals(selfDeptV10.getDeptUuid2())) {
                        parenetUuid = selfDeptV10.getDeptUuid1();
                    }
                }
            }
            if (StringUtils.isNotBlank(parenetUuid)) {
                DeptV10 parentDeptV10 = deptV10Map.get(parenetUuid);
                if(Objects.nonNull(parentDeptV10)){
                    finalSyncDeptList.add(parentDeptV10);
                }
            }
            finalSyncDeptList.add(selfDeptV10);
        } else if (SyncModeEnum.YIHUANG.getCode().equals(syncMode)) {
            return syncYiHuangDept(deptV10s, topDept);
        } else if (SyncModeEnum.WHOLE.getCode().equals(syncMode)) {
            finalSyncDeptList = deptV10s;
        }
        log.info("receiveIntentionService --> receiveIntention --> companyUuid-employeeUuid-employeePhone: {}, premisesId: {}, mobile: {}, finalSyncDeptList: {}",
                reqDto.getCompanyUuid() + "-" + reqDto.getEmployeeUuid() + "-" + reqDto.getEmployeePhone(),
                reqDto.getPremisesId(),
                reqDto.getMobile(),
                JSONObject.toJSONString(finalSyncDeptList));
        return syncChoosedDeptByRule(finalSyncDeptList, topDept, userDeptV10, syncMode);
    }

    public Department syncChoosedDeptByRule(List<DeptV10> finalSyncDeptList, Department topDept, DeptV10 userDeptV10, String syncMode){
        if(CollectionUtils.isEmpty(finalSyncDeptList)){
            return null;
        }
        Map<String, DepartmentDto> lastDeptMap = new HashMap<>();
        DepartmentDto lastAddDept = null;
        DepartmentDto returnDept = null;
        String lastDeptNo = "";
        for(int ii=0; ii<finalSyncDeptList.size(); ii++){
            DeptV10 deptV10 = finalSyncDeptList.get(ii);
            DepartmentDto addDeptDto = new DepartmentDto();
            addDeptDto.setDelFlag(DelFlagEnum.UNDEL.getNo());
            addDeptDto.setMerchantId(topDept.getMerchantId());
            if(ii == 0){
                addDeptDto.setCreateUserId(0L);
                addDeptDto.setParentId(topDept.getId());
                lastAddDept = editDepartment(addDeptDto, deptV10, "0");
                lastDeptNo = deptV10.getDeptNo();
                lastDeptMap.put(lastDeptNo, lastAddDept);
            }else{
                // 判断层级,并去除当前部门应该以哪一个作为最后新增作为父级
                // 数据中存在: 1级-2级-2级-3级-4级-4级-4级之类存在众多平级的情况
                // 需要根据当前处理的级别,反向查找其已经设定好的父级进行绑定
                // 原逻辑中: 1级下面的第二个2级,会绑定到前面一个2级下面
                // 这都是啥,看不懂的话来找我问吧.描述不下去了o(╥﹏╥)o
                // BANGFANG: 跳级获取部门数据
                if(deptV10.getLayer() == 2){
                    lastDeptNo = deptV10.getDeptUuid1();
                }else if(deptV10.getLayer() == 3){
                    lastDeptNo = deptV10.getDeptUuid2();
                    if(SyncModeEnum.BANGFANG.getCode().equals(syncMode)){
                        lastDeptNo = deptV10.getDeptUuid1();
                    }
                }else if(deptV10.getLayer() == 4){
                    lastDeptNo = deptV10.getDeptUuid3();
                    if(SyncModeEnum.BANGFANG.getCode().equals(syncMode)){
                        lastDeptNo = deptV10.getDeptUuid2();
                    }
                }else if(deptV10.getLayer() == 5){
                    lastDeptNo = deptV10.getDeptUuid4();
                    if(SyncModeEnum.BANGFANG.getCode().equals(syncMode)){
                        lastDeptNo = deptV10.getDeptUuid3();
                    }
                }else if(deptV10.getLayer() == 6){
                    lastDeptNo = deptV10.getDeptUuid5();
                    if(SyncModeEnum.BANGFANG.getCode().equals(syncMode)){
                        lastDeptNo = deptV10.getDeptUuid4();
                    }
                }else if(deptV10.getLayer() == 7){
                    lastDeptNo = deptV10.getDeptUuid6();
                    if(SyncModeEnum.BANGFANG.getCode().equals(syncMode)){
                        lastDeptNo = deptV10.getDeptUuid5();
                    }
                }else if(deptV10.getLayer() == 8){
                    lastDeptNo = deptV10.getDeptUuid7();
                    if(SyncModeEnum.BANGFANG.getCode().equals(syncMode)){
                        lastDeptNo = deptV10.getDeptUuid6();
                    }
                }
                // 当前部门的上一级部门
                if(StringUtils.isNotBlank(lastDeptNo)){
                    lastAddDept = lastDeptMap.get(lastDeptNo);
                }
                addDeptDto.setId(null);
                if(Objects.nonNull(lastAddDept)){
                    addDeptDto.setParentId(lastAddDept.getId());
                    // 当前部门保存后,变成最后一个部门.存入最后部门的Map
                    lastAddDept = editDepartment(addDeptDto, deptV10, lastDeptNo);
                    lastDeptMap.put(deptV10.getDeptUuid(), lastAddDept);
                }
            }
            if(deptV10.getDeptNo().equals(userDeptV10.getDeptNo())){
                // 新增部门与用户所在部门一致,返回此部门作为用户的绑定部门
                returnDept = lastAddDept;
            }
        }
        if(Objects.isNull(returnDept)){
            // 没有匹配当前用户的部门,以最后一个新增的部门作为后续用户绑定部门
            // 场景: 普通机构模式,默认添加1级及2级,当用户不在这两个级别中时,给第二级
            returnDept = lastAddDept;
        }
        return returnDept;
    }

    public Department syncYiHuangDept(List<DeptV10> deptV10s, Department topDept){
        Department userDepartment = null;
        DepartmentDto addDepartment = new DepartmentDto();
        addDepartment.setDelFlag(DelFlagEnum.UNDEL.getNo());
        addDepartment.setMerchantId(topDept.getMerchantId());
        addDepartment.setDepartmentCode(String.valueOf(topDept.getMerchantId()));
        addDepartment.setCreateUserId(10L);
        //区域名称
        String area = "";
        String storeUuid = null;
        for (DeptV10 deptV10 : deptV10s) {
            if (deptV10.getDeptName().endsWith("区") || deptV10.getDeptName().endsWith("部")) {
                addDepartment.setDepartmentName(deptV10.getDeptName());
                addDepartment.setAreaName(area);
                addDepartment.setParentId(topDept.getId());
                userDepartment = editDepartmentForRule(addDepartment, deptV10, "0");
                storeUuid = deptV10.getDeptUuid();
            }
            //添加门店  关联名称用 **区 + **店
            if (deptV10.getDeptName().endsWith("店")) {
                area = deptV10.getDeptName();
            }
            if (deptV10.getDeptName().endsWith("组") && null != userDepartment) {
                addDepartment.setDepartmentName(deptV10.getDeptName());
                addDepartment.setAreaName(area);
                addDepartment.setParentId(userDepartment.getId());
                userDepartment = editDepartmentForRule(addDepartment, deptV10, storeUuid);
            }
        }
        return userDepartment;
    }

    public OtherSysUser bindSaasUser(ReceiveIntentionReqDto reqDto, OtherCompany otherCompany, Department saasUserDept, Long devCompany) {
        Long agentCompany = otherCompany.getChannelCompanyId();
        // 绑定的Saas用户
        OtherSysUserDto otherSysUserDto = new OtherSysUserDto();
        otherSysUserDto.setCompanyId(agentCompany);
        otherSysUserDto.setIsDeleted(DelFlagEnum.UNDEL.getNo());
        otherSysUserDto.setOtherUserId(reqDto.getEmployeeUuid());
        otherSysUserDto.setOtherCompanyId(reqDto.getCompanyUuid());
        OtherSysUser otherSysUser = otherSysUserService.selectByDto(otherSysUserDto);
        log.info("receiveIntentionService --> receiveIntention --> companyUuid-employeeUuid-employeePhone: {}, premisesId: {}, mobile: {}, query old otherSysUser params: {}, result: {},查找渠道与此SAAS用户的绑定关系!",
                reqDto.getCompanyUuid() + "-" + reqDto.getEmployeeUuid() + "-" + reqDto.getEmployeePhone(),
                reqDto.getPremisesId(),
                reqDto.getMobile(),
                JSONObject.toJSONString(otherSysUserDto),
                JSONObject.toJSONString(otherSysUser));
        if (Objects.isNull(otherSysUser)) {
            // 查询渠道下所有分销商是否存在此手机号的用户
            PartnerInfoDto partnerInfoDto = new PartnerInfoDto();
            partnerInfoDto.setPhone(reqDto.getEmployeePhone());
            List<Long> companyIds = partnerInfoService.listGroupCompanyIdByCompanyId(devCompany, true);
            partnerInfoDto.setCompanyIds(companyIds);
            List<PartnerInfo> partnerInfos = partnerInfoService.checkRepeat(partnerInfoDto);
            log.info("receiveIntentionService --> receiveIntention --> companyUuid-employeeUuid-employeePhone: {}, premisesId: {}, mobile: {}, check repeat params: {}, results: {}, 未绑定SAAS,检查渠道下所有分销是否存在此手机号用户",
                    reqDto.getCompanyUuid() + "-" + reqDto.getEmployeeUuid() + "-" + reqDto.getEmployeePhone(),
                    reqDto.getPremisesId(),
                    reqDto.getMobile(),
                    JSONObject.toJSONString(partnerInfoDto),
                    partnerInfos.size());
            Long partnerId;
            if (!CollectionUtils.isEmpty(partnerInfos)) {
                // 已存在的用户,判断用户是否与报备人一致.
                // 同分销公司、手机号的用户
                Optional<PartnerInfo> opPartnerInfo = partnerInfos.stream()
                        .filter(item -> item.getAccountName().equals(reqDto.getEmployeeName())
                                && item.getPhone().equals(reqDto.getEmployeePhone())
                                && item.getHigherid().equals(agentCompany))
                        .findAny();
                log.info("receiveIntentionService --> receiveIntention --> companyUuid-employeeUuid-employeePhone: {}, premisesId: {}, mobile: {}, exists opPartnerInfo: {},判断报备的分销公司+用户姓名+用户手机号是否存在在已有账户中",
                        reqDto.getCompanyUuid() + "-" + reqDto.getEmployeeUuid() + "-" + reqDto.getEmployeePhone(),
                        reqDto.getPremisesId(),
                        reqDto.getMobile(),
                        JSONObject.toJSONString(opPartnerInfo.isPresent()?opPartnerInfo.get():"no body!!!"));
                if (opPartnerInfo.isPresent()) {
                    PartnerInfo partnerInfo = opPartnerInfo.get();
                    partnerId = partnerInfo.getId();
                    // 调整用户部门
                    partnerInfoDto = new PartnerInfoDto();
                    partnerInfoDto.setId(partnerId);
                    partnerInfoDto.setDeptId(saasUserDept.getId());
                    partnerInfoService.update(partnerInfoDto);

                    // 将已存在的旧Saas绑定删除,后续重新建立新的绑定关系
                    OtherSysUserDto otherDto = new OtherSysUserDto();
                    otherDto.setIsDeleted(DelFlagEnum.UNDEL.getNo());
                    otherDto.setChannelPartnerId(partnerId);
                    otherDto.setOtherCompanyId(reqDto.getCompanyUuid());
                    OtherSysUser oldSaasUser = otherSysUserService.selectByDto(otherDto);
                    if (Objects.nonNull(oldSaasUser)) {
                        otherDto.setIsDeleted(DelFlagEnum.DEL.getNo());
                        otherDto.setId(oldSaasUser.getId());
                        otherSysUserService.update(otherDto);
                    }
                } else {
                    log.info("receiveIntentionService --> receiveIntention --> agentCompany-employeeUuid-employeePhone: {}, repeat partnerInfos: {},手机号存在,但是与分销公司+用户名+手机号没匹配起来,账号属于他人,提示错误",
                            agentCompany + "-" + reqDto.getEmployeeName() + "-" + reqDto.getEmployeePhone(),
                            JSONObject.toJSONString(partnerInfos));
                    throw new RuntimeException("报备失败，该手机号已存在渠道王其他分销机构中，请联系管理员调整或禁用");
                }
            } else {
                // 添加分销人员
                PartnerInfoDto addInfo = new PartnerInfoDto();
                addInfo.setAccountName(reqDto.getEmployeeName());
                addInfo.setPhone(reqDto.getEmployeePhone());
                addInfo.setAccountType(MechanismAccountTypeEnum.individual.getNo());
                addInfo.setStatus(MechanismStatusEnum.enable.getNo());
                addInfo.setHigherid(agentCompany);
                addInfo.setPassword(PasswordUtil.md5Hex("12345678"));
                addInfo.setDeptId(saasUserDept.getId());
                addInfo.setDelFlag(DelFlagEnum.UNDEL.getNo());
                addInfo.setUserRole(UserRoleEnum.NOTHING.getNo());
                addInfo = partnerInfoService.create(addInfo);
                partnerId = addInfo.getId();
            }

            // 添加到第三方表中
            otherSysUserDto.setChannelPartnerId(partnerId);
            otherSysUserDto.setUserName(reqDto.getEmployeeName());
            otherSysUserDto.setUserPhone(reqDto.getEmployeePhone());
            otherSysUserService.create(otherSysUserDto);
            otherSysUser = otherSysUserService.selectByDto(otherSysUserDto);
            return otherSysUser;
        } else {
            PartnerInfo partnerInfo = partnerInfoService.selectById(otherSysUser.getChannelPartnerId());
            log.info("receiveIntentionService --> receiveIntention --> companyUuid-employeeUuid-employeePhone: {}, premisesId: {}, mobile: {}, exist partnerInfo: {},根据绑定关系得到分销用户信息",
                    reqDto.getCompanyUuid() + "-" + reqDto.getEmployeeUuid() + "-" + reqDto.getEmployeePhone(),
                    reqDto.getPremisesId(),
                    reqDto.getMobile(),
                    JSONObject.toJSONString(partnerInfo));
            // 手机号不一致
            if (!StringUtils.equals(partnerInfo.getPhone(), reqDto.getEmployeePhone())) {
                // 子表是否存在
                List<PartnerInfoAddition> partnerInfoAdditions = partnerInfoService.listPartnerInfoAddition(partnerInfo.getId());
                boolean flag = partnerInfoAdditions.stream()
                        .anyMatch(item -> StringUtils.equals(item.getPhone(), reqDto.getEmployeePhone()));
                log.info("receiveIntentionService --> receiveIntention --> companyUuid-employeeUuid-employeePhone: {}, premisesId: {}, mobile: {}, exist addition: {},判断是否为用户的子账户.true为是!",
                        reqDto.getCompanyUuid() + "-" + reqDto.getEmployeeUuid() + "-" + reqDto.getEmployeePhone(),
                        reqDto.getPremisesId(),
                        reqDto.getMobile(),
                        flag);
                if (!flag) {
                    //全新的手机号 做去重校验
                    PartnerInfoDto partnerInfoDto = new PartnerInfoDto();
                    partnerInfoDto.setPhone(reqDto.getEmployeePhone());
                    List<Long> companyIds = partnerInfoService.listGroupCompanyIdByCompanyId(devCompany, true);
                    partnerInfoDto.setCompanyIds(companyIds);
                    List<PartnerInfo> partnerInfos = partnerInfoService.checkRepeat(partnerInfoDto);
                    if (partnerInfos != null && partnerInfos.size() > 0) {
                        log.info("receiveIntentionService --> receiveIntention --> companyUuid-employeeUuid-employeePhone: {}, premisesId: {}, mobile: {}, exists partnerInfos: {},账号被占用,不能报备.",
                                reqDto.getCompanyUuid() + "-" + reqDto.getEmployeeUuid() + "-" + reqDto.getEmployeePhone(),
                                reqDto.getPremisesId(),
                                reqDto.getMobile(),
                                JSONObject.toJSONString(partnerInfos));
                        throw new RuntimeException("报备失败，该手机号在渠道王中归属于其他经纪人，请联系管理员调整或禁用");
                    }
                    //把partner里面的phone插入子表
                    PartnerInfoAddition partnerInfoAddition = new PartnerInfoAddition();
                    partnerInfoAddition.setPhone(partnerInfo.getPhone());
                    partnerInfoAddition.setHigherId(agentCompany);
                    partnerInfoAddition.setDelFlag(DelFlagEnum.UNDEL.getNo());
                    partnerInfoAddition.setCreateTime(new Date());
                    partnerInfoAddition.setPartnerId(partnerInfo.getId());
                    partnerInfoService.addPartnerInfoAddition(partnerInfoAddition);
                }
            }

            if (!RegexUtil.isMobileSimple(reqDto.getEmployeePhone())) {
                otherSysUserDto.setId(otherSysUser.getId());
                otherSysUserDto.setUserPhone(reqDto.getEmployeePhone());
                otherSysUserService.update(otherSysUserDto);
            }
            // 更新经纪人姓名
            PartnerInfoDto updateInfo = new PartnerInfoDto();
            updateInfo.setAccountName(reqDto.getEmployeeName());
            updateInfo.setPhone(reqDto.getEmployeePhone());
            updateInfo.setId(otherSysUser.getChannelPartnerId());
            updateInfo.setDeptId(saasUserDept.getId());
            partnerInfoService.update(updateInfo);
        }
        return otherSysUser;
    }

    //v10 对接  添加报备信息
    @Transactional
    public Map<String, String> addReportInfoFromV10(ReceiveIntentionReqDto reqDto, Premises premises, OtherSysUser otherSysUser, String agencyAccessToken, String assistantAccessToken, String devCompanyUuid) {
        Map<String, String> resultMap = new HashMap<String, String>();
        resultMap.put("errorCode", ReceiveIntentionErrorCodeEnum.CODE_000.getNo());

        //隐号报备处理
        String mobile = reqDto.getMobile();
        if (!ReportWayEnum.UNLIMITED.getNo().equals(premises.getReportWay()) && !ReportWayEnum.FULL_NUMBER.getNo().equals(premises.getReportWay())
                && StringUtils.isNotBlank(mobile) && mobile.length() > 4) {
            mobile = premisesService.convertMobileByPremises(mobile, premises.getId());
            reqDto.setMobile(mobile);
        }

        // 1. 报备
        PartnerInfo agentPi = partnerInfoService.selectById(otherSysUser.getChannelPartnerId());
        ReportProtectOverDueDto reportProtectOverDueDto = null;
        ReportValidOverDueDto reportValidOverDueDto = null;
        if (mobile.indexOf(StringConstant.THREE_STAR) < 0) {
            // 预计到访时间 V10可以传值为空
            if (reqDto.getReportVisit().getVisitTime() != null) {
                // 最短报备保护时间
                boolean checkSepcilTimeFlag = customerPremisesService.checkSpecialTime(reqDto.getReportVisit().getVisitTime().getTime(), premises);
                if (!checkSepcilTimeFlag) {
                    String errorMsg = ReceiveIntentionErrorCodeEnum.CODE_006.getMsg();
                    resultMap.put("msg", errorMsg);
                    resultMap.put("success", "3");
                    resultMap.put("errorCode", ReceiveIntentionErrorCodeEnum.CODE_006.getNo());
                    return resultMap;
                }
            }

            boolean visitFlag = customerPremisesService.checkVisitRepeat(0L, premises, mobile);
            if (visitFlag) {
                //002 客户已到访
                String errorMsg = "手机号为【" + mobile + "】的客户已到访该楼盘【" + premises.getName() + "】,无法再次报备!";
                resultMap.put("msg", ReceiveIntentionErrorCodeEnum.CODE_002.getMsg());
                resultMap.put("success", "3");
                resultMap.put("errorCode", ReceiveIntentionErrorCodeEnum.CODE_002.getNo());
                return resultMap;
            }

            // 3、报备保护逾期校验
            // 3.1、判断能否报备--> 不能时返回
            // 3.2、能报备: 判断保护时间应该是多久~
            reportProtectOverDueDto = premisesOverdueService.checkReportProtect(premises, agentPi, mobile);
            log.info("cpreportserviceimpl --> reportProtectOverDueDto: {}", JSONObject.toJSONString(reportProtectOverDueDto));
            if (!reportProtectOverDueDto.getCanReport().booleanValue()) {
                String errorMsg = "手机号为【" + mobile + "】的客户在此楼盘【" + premises.getName() + "】处于报备保护期内，目前不可报备<br/>";
                resultMap.put("msg", ReceiveIntentionErrorCodeEnum.CODE_002.getMsg());
                resultMap.put("success", "3");
                resultMap.put("errorCode", ReceiveIntentionErrorCodeEnum.CODE_002.getNo());
                return resultMap;
            }

            // 报备有效逾期校验
            reportValidOverDueDto = premisesOverdueService.checkReportValid(premises, agentPi, mobile);
            log.info("cpreportserviceimpl --> reportValidOverDueDto: {}", JSONObject.toJSONString(reportValidOverDueDto));
            if (!reportValidOverDueDto.getCanReport().booleanValue()) {
                String errorMsg = "报备无效次数过多,目前不可报备<br/>";
                resultMap.put("msg", errorMsg);
                resultMap.put("success", "3");
                resultMap.put("errorCode", ReceiveIntentionErrorCodeEnum.CODE_001.getNo());
                return resultMap;
            }
        }

        //M2校验
        //查看经纪人所属渠道商是否与M2绑定
        Company devCompany = companyService.selectById(premises.getCompanyId());

        // 校验手机号在M2的唯一性
        if (ReportExternalConvert.repeatSwitchForM2(devCompany, premises.getProjectCodeM2())) {
            CommonResDTO commonResDto = reportCommonService.isExistsInM2(premises.getProjectCodeM2(), devCompany.getMerchantCode(), mobile, m2ApiConfig.getM2RequestUrl());
            if (ResultEnum.FAIL.getNo().equals(commonResDto.getResult())) {
                resultMap.put("msg", "报备无效，M2案场管理中该楼盘【" + premises.getName() + "】已有此客户记录，无法重复报备");
                resultMap.put("success", "3");
                resultMap.put("errorCode", ReceiveIntentionErrorCodeEnum.CODE_003.getNo());
                return resultMap;
            }
        }

        // 1.2写入报备
        CustomerPremisesDto cpDto = new CustomerPremisesDto();
        //推荐人
        cpDto.setRecommenderUuid(reqDto.getRecommenderUuid());
        cpDto.setCommissionWay(premises.getCommissionWay());
        cpDto.setStaffId(otherSysUser.getChannelPartnerId());
        cpDto.setPremisesId(Long.parseLong(reqDto.getPremisesId()));
        cpDto.setMobile(mobile);
        cpDto.setName(reqDto.getName());
        cpDto.setGender(reqDto.getGender());
        cpDto.setEmail(reqDto.getEmail());
        cpDto.setConfirmStatus(ConfirmStatusEnum.confirm.getNo());
        cpDto.setCustomerStatus(CustomerStatusEnum.normal.getNo());
        cpDto.setRemark(reqDto.getRemark());
        cpDto.setCompanyId(premises.getCompanyId());
        cpDto.setStaffCompanyId(otherSysUser.getCompanyId());
        //1:已收房源、2: 海外房源
        cpDto.setPremisesSource(premises.getFromSource());
        cpDto.setCommissionAmount("0");
        cpDto.setReward(StringUtils.isEmpty(premises.getReward()) == true ? new BigDecimal("0") : new BigDecimal(premises.getReward()));
        cpDto.setDomesticProportion(String.valueOf(premises.getZjCommissionRatio()));
        cpDto.setComplaintsNumber(0L);
        // 2. 写跟进
        //报备保护时长
        reportCommonService.setReportProtectOverDueTime(cpDto, reportProtectOverDueDto);
        //报备有效时长
        reportCommonService.setReportValidOverDueTime(cpDto, reportValidOverDueDto);
        //待看保护时长
        String saveDays = premises.getSaveDays();
        Calendar calendar = Calendar.getInstance();
        if (StringUtils.isNotEmpty(saveDays)) {
            try {
                calendar.add(Calendar.MINUTE, Integer.parseInt(saveDays));
                cpDto.setLookPeriodTime(calendar.getTime());
            } catch (Exception e) {
                cpDto.setLookPeriodTime(calendar.getTime());
            }
        }

        cpDto.setReportType(ReportTypeEnum.type_1.getNo());

        //带看保护时间
        Calendar visitProtectCalendar = customerPremisesService.getVisitProtectCalendar(Long.parseLong(reqDto.getPremisesId()), null);
        cpDto.setVisitProtectTime(visitProtectCalendar.getTime());
        // 预计到访时间 V10可以传值为空
        if (reqDto.getReportVisit().getVisitTime() != null) {
            //期望带看保护时间
            if (reqDto.getReportVisit().getVisitTime() != null) {
                cpDto.setHopeVisitTime(reqDto.getReportVisit().getVisitTime());
            }
        }
        Long principalId = customerPremisesService.getPricipalId(cpDto.getStaffId());
        cpDto.setPrincipalId(principalId);
        //添加报备冗余字段
        cpDto.setReportPhone(reqDto.getEmployeePhone());
        if (!TimeUnitTypeEnum.NONE.getNo().equals(premises.getSpecialTimeType()) && StringUtils.isNotBlank(premises.getSpecialTime())) {
            calendar = Calendar.getInstance();
            String specialTime = premises.getSpecialTime();
            calendar.add(Calendar.MINUTE, Integer.parseInt(specialTime));
            cpDto.setVisitPastTime(calendar.getTime());
        }
        //发送微信消息
        log.info("receive intention body = ", JSONObject.toJSONString(cpDto));
        cpDto = customerPremisesService.create(cpDto);
        if (cpDto.getId() != null) {
            resultMap.put("reportId", cpDto.getId().toString());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            resultMap.put("reportDate", sdf.format(cpDto.getCreateTime()));
        }
        //添加约看信息
        ReportVisit rv = reqDto.getReportVisit();
        if (rv != null) {
            ReportVisitDto reportVisitDto = new ReportVisitDto();
            BeanUtils.copyProperties(rv, reportVisitDto);
            reportVisitDto.setReportId(cpDto.getId());
            reportVisitDto.setIsDeleted(DelFlagEnum.UNDEL.getNo());
            reportVisitService.create(reportVisitDto);
        }
        //添加报备关系
        PremisesRelationExternalDto preDto = new PremisesRelationExternalDto();
        preDto.setSysId(ExternalSysEnum.V10.getCode());
        preDto.setPremisesId(premises.getId());
        preDto.setExternalCompanyId(reqDto.getCompanyUuid());
        preDto.setIsDeleted(DelFlagEnum.UNDEL.getNo());
        List<PremisesRelationExternal> preList = premisesRelationExternalService.selectListByDto(preDto);

        ReportExternalDto reportExternal = new ReportExternalDto();
        reportExternal.setIsDeleted(DelFlagEnum.UNDEL.getNo());
        reportExternal.setReportId(cpDto.getId());
        reportExternal.setReportUuid(rv.getIntentionUuid());
        reportExternal.setPremiseId(premises.getId());
        reportExternal.setMobileRule(reqDto.getMobileRule());
        reportExternal.setReportMobile(reqDto.getMobile());
        if (preList != null && preList.size() > 0) {
            reportExternal.setPremisesUuid(preList.get(0).getExternalId());
        }

        reportExternal.setSysId(ExternalSysEnum.V10.getCode());
        reportExternalService.create(reportExternal);

        //添加自定义报备模板信息
        if (!CollectionUtils.isEmpty(reqDto.getReportModelInfos())) {
            reportModelApiService.setReportModeInfo(reqDto.getReportModelInfos(), cpDto.getId());
        }

        //写带状态跟进记录
        reportCommonService.addReportFollow(cpDto, FollowTypeEnum.CHANNEL.getNo(), "报备客户", String.valueOf(cpDto.getStaffId()), reqDto.getRemark());

        //发送微信消息
        log.info("V10报备,获取消息推送信息: companyUuid = " + devCompanyUuid + ", agencyToken = " + agencyAccessToken + ", assistantToken = " + assistantAccessToken);
        if (StringUtils.isNotEmpty(devCompanyUuid)) {
            wxTemplateMsgService.sendReportSuccessTemplateMsgForV10(agencyAccessToken, assistantAccessToken, cpDto, devCompanyUuid);
        }

        //发送报备短信
        PartnerInfo partnerInfo = partnerInfoService.selectById(otherSysUser.getChannelPartnerId());

        //组装短信发送内容Map
        Map<String, String> smsMap = new HashMap<>();
        smsMap.put("premisesName", premises.getName());
        Company company = companyService.selectById(partnerInfo.getHigherid());
        if (null != company) {
            smsMap.put("agentCompany", company.getCompanyName());
        }
        Department dept = departmentDao.selectById(partnerInfo.getDeptId());
        if (null != dept) {
            smsMap.put("agentDept", dept.getDepartmentName());
        }
        smsMap.put("agentName", partnerInfo.getAccountName());
//		smsMap.put("agentPhone", partnerInfo.getPhone()); V10选择的手机号
        smsMap.put("agentPhone", reqDto.getEmployeePhone());
        smsMap.put("cusName", cpDto.getName());
        smsMap.put("mobile", reqDto.getMobile());
        reportCommonService.sendReportSms(premises, partnerInfo, smsMap, cpDto, "V10同步报备");

        resultMap.put("success", ResultEnum.SUCCESS.getNo());
        resultMap.put("remark", JSONObject.toJSONString(smsMap));
        return resultMap;
    }


    private boolean isInUserMap(ReceiveIntentionReqDto reqDto) {
        synchronized (concurrentHashMap) {
            if (concurrentHashMap.containsKey(reqDto.getEmployeeUuid())) {
                return true;
            } else {
                concurrentHashMap.put(reqDto.getEmployeeUuid(), reqDto);
            }
        }
        return false;
    }

    //检查是否已同步过部门
    public OtherSysDept checkDeptV10(DepartmentDto addDepartment, DeptV10 deptV10) {
        if (StringUtils.isBlank(deptV10.getDeptUuid())) {
            return null;
        }
        OtherSysDeptDto otherSysDept = new OtherSysDeptDto();
        otherSysDept.setChannelCompanyId(addDepartment.getMerchantId());
        otherSysDept.setDeptUuid(deptV10.getDeptUuid());
        otherSysDept.setDelFlag(DelFlagEnum.UNDEL.getNo());
        OtherSysDept bindDept = otherSysDeptService.selectByDto(otherSysDept);
        if (Objects.isNull(bindDept)) {
            return null;
        }
        return bindDept;
    }

    private DepartmentDto editDepartment(DepartmentDto addDepartment, DeptV10 deptV10, String parentV10Id) {
        // 变更用户绑定部门的层级
        if(Objects.nonNull(addDepartment.getParentId())){
            Department parentDept = departmentDao.selectById(addDepartment.getParentId());
            addDepartment.setLayer(parentDept.getLayer() + 1);
        }
        addDepartment.setDepartmentName(deptV10.getDeptName());
        OtherSysDept checkOtherSysDept = checkDeptV10(addDepartment, deptV10);
        if (Objects.isNull(checkOtherSysDept)) {
            // 查询是否有相同名称，且未绑定V10的部门
            Department dept = null;
            if (StringUtils.isNotEmpty(parentV10Id)) {
                DepartmentDto dto = new DepartmentDto();
                dto.setDepartmentName(deptV10.getDeptName());
                dto.setMerchantId(addDepartment.getMerchantId());
                //SAAS10-458 通过名称和商户查询部门，过滤掉Level = 0 的数据
                dto.setIsFilterParentLevel(true);
                List<Department> departments = departmentDao.selectListByDto(dto);
                if(!CollectionUtils.isEmpty(departments)){
                    dept = departments.get(0);
                    if (!"0".equals(parentV10Id)){
                        for (Department department : departments) {
                            if (addDepartment.getParentId().equals(department.getParentId())) {
                                dept = department;
                            }
                        }
                    }
                }
            }
            if (Objects.isNull(dept)) {
                addDepartment.setDepartmentName(deptV10.getDeptName());
                addDepartment = departmentDao.create(addDepartment);
            } else {
                addDepartment.setId(dept.getId());
                dept.setParentId(addDepartment.getParentId());
                DepartmentDto updateDept = new DepartmentDto();
                BeanUtils.copyProperties(dept, updateDept);
                departmentDao.update(updateDept);
            }

            OtherSysDeptDto otherSysDept = new OtherSysDeptDto();
            otherSysDept.setDelFlag(DelFlagEnum.UNDEL.getNo());
            otherSysDept.setDeptUuid(deptV10.getDeptUuid());
            Long merchantId = addDepartment.getMerchantId();
            Long channelDeptId = addDepartment.getId();
            if(Objects.nonNull(dept)){
                merchantId = dept.getMerchantId();
                channelDeptId = dept.getId();
            }
            otherSysDept.setChannelCompanyId(merchantId);
            otherSysDept.setChannelDeptId(channelDeptId);
            otherSysDept.setSysId(ExternalSysEnum.V10.getCode());
            otherSysDept.setDeptName(deptV10.getDeptName());
            otherSysDept.setDeptNo(deptV10.getDeptNo());
            otherSysDept.setParentId(parentV10Id);
            otherSysDeptService.create(otherSysDept);

        } else {
            addDepartment.setId(checkOtherSysDept.getChannelDeptId());
            departmentDao.update(addDepartment);
        }
        return addDepartment;
    }

    /**
     * 更新第三方部门关联表，更新部门表 目前仅懿黄
     *
     * @param addDepartment
     * @param deptV10
     * @return
     */
    public Department editDepartmentForRule(DepartmentDto addDepartment, DeptV10 deptV10, String parentId) {
        OtherSysDept checkOtherSysDept = null;
        OtherSysDeptDto otherSysDept = new OtherSysDeptDto();
        otherSysDept.setDelFlag(DelFlagEnum.UNDEL.getNo());
        otherSysDept.setDeptUuid(deptV10.getDeptUuid());
        otherSysDept.setSysId(ExternalSysEnum.V10.getCode());
        otherSysDept.setDeptName(deptV10.getDeptName());
        otherSysDept.setDeptNo(deptV10.getDeptNo());
        otherSysDept.setParentId(parentId);
        // 变更用户绑定部门的层级
        if(Objects.nonNull(addDepartment.getParentId())){
            Department parentDept = departmentDao.selectById(addDepartment.getParentId());
            addDepartment.setLayer(parentDept.getLayer() + 1);
        }

        if ((checkOtherSysDept = checkDeptV10(addDepartment, deptV10)) == null) {
            addDepartment = departmentDao.create(addDepartment);
            otherSysDept.setChannelCompanyId(addDepartment.getMerchantId());
            otherSysDept.setChannelDeptId(addDepartment.getId());
            otherSysDeptService.create(otherSysDept);
        } else {
            addDepartment.setId(checkOtherSysDept.getChannelDeptId());
            departmentDao.update(addDepartment);
            //更新第三方部门关系
            otherSysDept.setId(checkOtherSysDept.getId());
            otherSysDeptService.update(otherSysDept);
        }
        return addDepartment;
    }


    public void noticeV10ForReport(Map<String, String> map, ReceiveIntentionReqDto reqDto, Long companyId, Premises premises) {
        if (null == map) {
            return;
        }
        if (!map.containsKey("errorCode")) {
            return;
        }
        ReportVisitDto rv = reqDto.getReportVisit();
        if (rv == null || StringUtils.isEmpty(rv.getIntentionUuid())) {
            return;
        }
        String specialTimeMsg = "小于最短报备时间,报备无效，此楼盘至少需要提前%d%s报备，无法临时报备";
        if (ReceiveIntentionErrorCodeEnum.CODE_006.getNo().equals(map.get("errorCode"))) {
            if (TimeUnitTypeEnum.DAY.getNo().equals(premises.getSpecialTimeType())) {
                int time = Integer.parseInt(premises.getSpecialTime()) / 1440;
                specialTimeMsg = String.format(specialTimeMsg, time, "天");
            } else if (TimeUnitTypeEnum.HOUR.getNo().equals(premises.getSpecialTimeType())) {
                int time = Integer.parseInt(premises.getSpecialTime()) / 60;
                specialTimeMsg = String.format(specialTimeMsg, time, "小时");
            } else if (TimeUnitTypeEnum.MINUT.getNo().equals(premises.getSpecialTimeType())) {
                int time = Integer.parseInt(premises.getSpecialTime());
                specialTimeMsg = String.format(specialTimeMsg, time, "分钟");
            } else {
                specialTimeMsg = null;
            }
        } else {
            specialTimeMsg = null;
        }
        //调用接口通知调用方
        BaseResponseDto baseResponseDto = v10BindService.synsNoticeForReport(rv.getIntentionUuid(), map.get("errorCode"), companyId, specialTimeMsg);
    }

}
